package com.camel.base.controller;

import com.alibaba.nacos.common.utils.UuidUtils;
import com.camel.base.domain.SurveyDesign;
import com.camel.base.enums.SurveyState;
import com.camel.base.model.ZsOption;
import com.camel.base.model.ZsQuestion;
import com.camel.base.model.ZsSurvey;
import com.camel.base.service.ZsOptionService;
import com.camel.base.service.ZsQuestionService;
import com.camel.base.service.ZsSurveyService;
import com.camel.base.utils.ExportExcelUtils;
import com.camel.core.controller.BaseCommonController;
import com.camel.core.entity.Result;
import com.camel.core.exceptions.CustomException;
import com.camel.core.service.BaseCommonService;
import com.camel.core.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author camel
 */
@RestController
@RequestMapping("zsSurvey")
public class ZsSurveyController extends BaseCommonController<ZsSurvey> {

    @Autowired
    private ZsSurveyService<ZsSurvey> service;

    @Autowired
    private ZsQuestionService<ZsQuestion> questionService;

    @Autowired
    private ZsOptionService<ZsOption> zsOptionService;

    @Override
    public Result update(@RequestBody ZsSurvey entity) {
        // 查询库里的问卷信息
        ZsSurvey surveyDb = service.getById(entity.getId());

        if(entity.getState() != surveyDb.getState()) {
            if(surveyDb.getState().getValue() > 1 && entity.getState().equals(SurveyState.EDIT)) {
                throw new CustomException("已经发布的问卷不能重回编辑状态");
            }
        }
        return super.update(entity);
    }

    @Override
    public boolean deleteAble(Serializable id) {
        ZsSurvey byId = service.getById(id);
        if (ObjectUtils.isEmpty(byId)) {
            throw new CustomException("删除失败: 问卷不存在");
        }
        if (!byId.getState().equals(SurveyState.CREATED)) {
            throw new CustomException("删除失败: 已经开始调查的问卷不能删除");
        }
        return true;
    }

    /**
     * 问卷设计 保存
     *
     * @param design
     * @return
     */
    @Transactional(propagation= Propagation.SUPPORTS)
    @PostMapping("/design")
    public Result design(@RequestBody SurveyDesign design) {
        // 取出数据库的， 拿出参数比对， 包含则修改， 不包含则新增， 缺少则删除
        List<ZsQuestion> zsQuestions = questionService.selectList(design.getSurvey().getId());

        for (ZsQuestion paramsQ : design.getQuestions()) {
            // 如果参数中的数据没有id,则新增
            if (ObjectUtils.isEmpty(paramsQ.getId())) {
                // 失败会抛异常
                addQUestion(paramsQ, design.getSurvey());
                continue;
            }
        }

        // 参数中的问题
        for (ZsQuestion dbQ : zsQuestions) {
            boolean paramsQexsit = false;
            // 如果参数中的问题已经有了，直接更新
            for (ZsQuestion  paramsQ: design.getQuestions()) {
                if (dbQ.getId().equals(paramsQ.getId())) {
                    updateQuestion(paramsQ);
                    paramsQexsit = true;
                    updateOption(paramsQ, dbQ, design.getSurvey());
                    break;
                }
            }
            if (!paramsQexsit) {
                // 不存在的情况要删除问题
                deleteQuestion(dbQ);
                for (ZsOption o : dbQ.getChildren()) {
                    // 连带选项也删除
                    deleteOption(o);
                }
            }
        }
        return ResultUtil.success(design);
    }

    public boolean contanisQ(List<ZsQuestion> questions, ZsQuestion question) {
        return true;
    }

    /**
     * 新增问题
     *
     * @param question 问题信息
     * @param survey   问卷信息
     * @return
     */
    public void addQUestion(ZsQuestion question, ZsSurvey survey) {
        question.setSurveyId(survey.getId());
        question.setMrid(UuidUtils.generateUuid());
        boolean save = questionService.save(question);
        if (save) {
            for (ZsOption option : question.getChildren()) {
                option.setSurveyId(survey.getId());
                option.setMrid(UuidUtils.generateUuid());
                option.setQuestionId(question.getId());
                boolean b = zsOptionService.save(option);
                if (!b) {
                    throw new RuntimeException("保存选项失败");
                }
            }
        } else {
            throw new RuntimeException("保存问题失败");
        }
    }

    /**
     * 修改问题
     *
     * @param question
     */
    public void updateQuestion(ZsQuestion question) {
        if(StringUtils.isEmpty(question.getMrid())) {
           question.setMrid(UuidUtils.generateUuid());
        }
        if (!questionService.updateById(question)) {
            throw new CustomException("修改问题失败");
        }
    }

    /**
     * 删除问题
     *
     * @param question
     */
    public void deleteQuestion(ZsQuestion question) {
        if (!questionService.removeById(question.getId())) {
            throw new CustomException("删除问题失败");
        }
    }

    /**
     * 修改选项
     *
     * @param paramsQ
     * @param dbQ
     */
    public void updateOption(ZsQuestion paramsQ, ZsQuestion dbQ, ZsSurvey survey) {
        // 如果选项为空 则删除所有库里选项
        if(ObjectUtils.isEmpty(paramsQ.getChildren())) {
            zsOptionService.removeByIds(dbQ.getChildren().stream().map(ZsOption::getId).collect(Collectors.toList()));
            return;
        }
        if(ObjectUtils.isEmpty(dbQ.getChildren())) {
            for (ZsOption child : paramsQ.getChildren()) {
                if(StringUtils.isEmpty(child.getMrid())) {
                    child.setMrid(UuidUtils.generateUuid());
                }
            }

            zsOptionService.saveBatch(paramsQ.getChildren());
            return;
        }

        for (ZsOption dbO : dbQ.getChildren()) {
            boolean pIndb = false;
            for (ZsOption paramO : paramsQ.getChildren()) {
                if(StringUtils.isEmpty(paramO.getMrid())) {
                    paramO.setMrid(UuidUtils.generateUuid());
                }
                if(ObjectUtils.isEmpty(paramO.getId())) {
                    pIndb = true;
                    paramO.setQuestionId(paramsQ.getId());
                    paramO.setSurveyId(survey.getId());
                    zsOptionService.save(paramO);
                }
                if(paramO.getId().equals(dbO.getId())) {
                    pIndb = true;
                    zsOptionService.updateById(paramO);
                }
            }
            if(!pIndb) {
                zsOptionService.removeById(dbO.getId());
            }
        }
    }

    /**
     * 删除问题
     *
     * @param option
     */
    public void deleteOption(ZsOption option) {
        if (!zsOptionService.removeById(option.getId())) {
            throw new CustomException("删除问题失败");
        }
    }

    @Override
    public Result save(ZsSurvey entity) {
        if(StringUtils.isEmpty(entity.getCode())) {
            String code = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            entity.setCode(code);
        }
        return super.save(entity);
    }

    /**
     * 设计器查询已经有的数据
     *
     * @param entity 问卷
     * @return
     */
    @GetMapping("/design")
    public Result designInfo(ZsSurvey entity) {
        List<ZsQuestion> zsQuestions = questionService.selectList(entity.getId());
        for (ZsQuestion zsQuestion : zsQuestions) {
            zsQuestion.setAnswers(new ArrayList<>());
        }

        return ResultUtil.success(zsQuestions);
    }

    @PostMapping("/testJSON")
    public Result postJSON(@RequestBody ZsSurvey survey) {
        return ResultUtil.success(survey);
    }

    @GetMapping("/template/{id}")
    public void template(@PathVariable Integer id, HttpServletResponse response) {
        ExportExcelUtils.export(service.getImportTemplate(id) ,"", response);
    }

    @Override
    public BaseCommonService<ZsSurvey> getiService() {
        return service;
    }

    @Override
    public String getMouduleName() {
        return "问卷";
    }
}
